/****************************************************************************************
* Title: Yam
*****************************************************************************************
* File: 
* Authors: Joao Leonardo Fragoso, Roger da Silva Pereira, Robim Araujo Pacheco
* Company: UERGS - Unidade Guaiba
* Creation: 2013/06/15
*****************************************************************************************
* Description: GO Model for YGO Project Memory. It uses RAM as storage element.
               This block just provide correct int32erface to others modules
*/

package ygo

import (
	"fmt"
	"os"
	"time"
	"dumpwave"
)
////////////////////////////////////////////////////////
//variaveis para criação do arquivo value dump chanel
var inicio time.Time
var f *os.File
////////////////////////////////////////////////////////


////////////////////////////////////////////////////////
//declaração de canais structs usados na ligação dos blocos
///////////////////////////////////////////////////////

type DECO struct{
	CP0_COMMAND, CP0_BDS uint32
}

type DERE struct{
	RF_COMMAND, RS, RT, RD uint32 // Em caso de instruções do tipo Load/Store/Branch RS=BASE RD=OFFSET
}

type DEDM struct{
	DMUX_COMMAND, DMUX_UNIT uint32
}

type DEMU struct{
	MUX_COMMAND, MUX_UNIT uint32
}

type ALMU struct{
	EXEC_TO_REG  int32
	CANCELLED    bool
}

type MURE struct{
	WRITE      int32
	CANCELLED  bool
}

type REDM struct{
	BUS1, BUS2 int32
}

type DMAL struct{
	BUS1, BUS2 int32
}

type DEPC struct{
	PC_COMMAND, PC_IMMEDIATE, PC_OFFSET, PC_BUFFERS uint32
}

type DEAL struct{
	CMD, IMMEDIATE uint32
}

////////////////////////////////////////////////////////
//bloco microprocessador mips: YAM
///////////////////////////////////////////////////////


func Yam(
	instruction_address  chan uint32,
	instruction          chan uint32,
	ls_addr              chan uint32,
	ls_rw                chan bool,
	ls_data_in           chan int32,
	ls_data_out          chan int32) {

	decodeMux := make(chan DEMU)
	aluMux := make(chan ALMU)
	decodeAlu := make(chan DEAL)
	decodeRegister := make(chan DERE)
	muxRegister := make(chan MURE)
	aluCop0_exception := make(chan int32)
	decodeCop0 := make(chan DECO)
	registerDmux := make(chan REDM)
	dmuxAlu := make(chan DMAL)
	decodeDmux := make(chan DEDM)
	decodePC := make(chan DEPC)
	aluPc := make(chan uint32)
	cop0Decode := make (chan uint32)
	pcCop0	:= make (chan uint32)
	cop0Pc	:= make (chan uint32)
	aluDecode_branch := make (chan uint32)
	decodeYam := make (chan uint32)
	////////////////////////////////////////////////////////
	//cria/abre o arquivo em modo de escrita
	//disparo do relógio para sincronia dos values dumps
	///////////////////////////////////////////////////////

	dumpwave.IniciaWave(datainiciatial)

	fmt.Println("[YAM] Iniciando PC")
	go pc(instruction_address, decodePC,aluPc,pcCop0,cop0Pc)

	fmt.Println("[YAM] Iniciando decode")
	go decode(instruction, cop0Decode, decodeAlu, decodeCop0, decodeRegister, decodeDmux, decodeMux, decodePC, aluDecode_branch,decodeYam)

	fmt.Println("[YAM] Iniciando mux")
	go mux(decodeMux, aluMux, muxRegister)

	fmt.Println("[YAM] Iniciando dmux")
	go dmux(decodeDmux, registerDmux, dmuxAlu)

	fmt.Println("[YAM] Iniciando register")
	go register(decodeRegister, muxRegister, registerDmux)

	fmt.Println("[YAM] Iniciando ALU")
	go alu(decodeAlu, dmuxAlu, aluMux, aluCop0_exception, ls_addr, ls_rw, ls_data_in, ls_data_out, aluPc, aluDecode_branch)

	fmt.Println("[YAM] Iniciando COP0")
	go cop0(cop0Decode, aluCop0_exception, decodeCop0, pcCop0,cop0Pc)

	<-decodeYam
	fmt.Println("[YAM] HALT")
	os.Exit(0)
}
